﻿using Microsoft.WindowsAPICodePack.Taskbar;
using Serietheque.Fenetres;
using Serietheque.Properties;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using TvdbLib.Data;

namespace Serietheque
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        #region Membres

        private bool m_isNasAlive;
        private ObservableCollection<Episodes> m_playListEpisodesCollection;
        private string m_traitementText;

        //private Tvdb m_tvdb;

        private Episodes objEmpToEdit;

        //Create an ObjectContext instance based on Entiti
        private bddEntities seriesContext;

        public event PropertyChangedEventHandler PropertyChanged;
        private string m_connectionStr;
        #endregion Membres

        #region Propriété

        public bool IsNasAlive
        {
            get { return m_isNasAlive; }
            set
            {
                if (value != this.m_isNasAlive)
                {
                    this.m_isNasAlive = value;
                    NotifyPropertyChanged("NasAlive");
                };
            }
        }

        public ObservableCollection<Episodes> PlayListEpisodesCollection
        {
            get { return m_playListEpisodesCollection; }
            set
            {
                if (value != this.m_playListEpisodesCollection)
                {
                    this.m_playListEpisodesCollection = value;
                    NotifyPropertyChanged("PlayListEpisodesCollection");
                };
            }
        }

        private string TraitementText
        {
            get { return m_traitementText; }
            set
            {
                if (value != this.m_traitementText)
                {
                    this.m_traitementText = value;
                    NotifyPropertyChanged("TraitementText");
                };
            }
        }
        #endregion Propriété

        public MainWindow()
        {
            // AddConnectionStrings();
        }

        //------ INotifyPropertyChanged ------//
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        #region Evenenemnt

        protected override void OnPreviewMouseWheel(MouseWheelEventArgs e)
        {
            base.OnPreviewMouseWheel(e);

            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
            {
                e.Handled = true;
                Zoom.Value += (e.Delta > 0) ? 7 : -7;
            }
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            //a travailler
            seriesContext.SaveChanges();
            Settings.Default.DetailSerie = false;
            Settings.Default.Save();
        }

        //------ Window ------//
        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //affiche par defaut cad les images des series.
            // ShowSeriesOnly();
            //si le chemin du cache n'existe pas
            if (Settings.Default.Cache == "")
            {
                //Set setting : Chemin SERIE if not defined
                if (String.IsNullOrEmpty(Settings.Default.Serie))
                    Settings.Default.Serie = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos) + "\\Séries";
                //Set setting : Chemin CACHE if not defined
                if (String.IsNullOrEmpty(Settings.Default.Cache))
                    Settings.Default.Cache = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Serietheque\\Cache";
                //Save setting
                Settings.Default.Save();

                //ouverture fenetre preference
                Preference pref = new Preference();
                pref.ShowDialog();

            }

            if (Settings.Default.Cache == "")
                this.Close();

            if (!Directory.Exists(Settings.Default.Cache))
                Directory.CreateDirectory(Settings.Default.Cache);

            //AddConnectionStrings();
            try
            {
                m_connectionStr = @"metadata=res://*/SeriesModelEntity.csdl|res://*/SeriesModelEntity.ssdl|res://*/SeriesModelEntity.msl;provider=System.Data.SqlClient;provider connection string=';data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=" + Settings.Default.Cache + "\\bdd.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework';";
                //créer le context
                seriesContext = new bddEntities(m_connectionStr);
                //seriesContext.Database.Connection.ConnectionString = new ConnectionStringSettings("SeriesEntities", @"metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=';data source=(LocalDB)\v11.0;attachdbfilename=" + Settings.Default.Cache + "\\bdd.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework';", "System.Data.EntityClient").ToString();
                seriesContext.Database.Initialize(true);
                //créer la bdd au cas ou elle n'existe pas
                seriesContext.Database.CreateIfNotExists();
            }
            catch (Exception)
            {
                Close();
            }

            if (seriesContext.Database.Exists())
            {
                //seriesContext.Database.Connection.Open();
                //load async des donnée de l'EF
                await seriesContext.Series.LoadAsync();
                await seriesContext.Episodes.LoadAsync();
                await seriesContext.Saisons.LoadAsync();

                //vide la listebox au cas ou
                ListBoxImage.Items.Clear();

                //Charge les series.

                //definie le datacontext de l'app
                // this.LayoutRoot.DataContext = seriesContext.Series.Local.OrderBy(s => s.Name);


                ListBoxImage.DataContext = seriesContext.Series.Local.OrderBy(s => s.Name);
                //ListBoxImage.Items.Filter = Settings.Default.OnlyShowFollowed ? new Predicate<object>(ShowFollowed) : null;
                //taille de tte les series
                //string taille = UpdateSizeInStatutBar();
                //infoNbrTailleST.Text = seriesContext.Episodes.Count() + " Episodes - " + taille;

                //pour pas qu'il n'y ai de series selectionné
                ListBoxSaison.SelectedItem = null;

                //on affiche la listebox avec les serie uniquement
                ShowSeriesOnly();
                HideProgress();

                await SetNumberOfNoViewedEpisodes();
                await SetNumberOfRecentEpisodes();
            }
            else
            {
                //entity pas chargé
            }
        }



        #region Menu

        private void Menu_FindEpisodes_Click(object sender, RoutedEventArgs e)
        {
            //List<string> files = CreateFilesList(Settings.Default.Serie, true);
            //List<string> files = CreateFilesList("D:\\InProgres\\", false);
            //FilesTreatment(files);
        }

        private void Menu_FindNewEpisodes_Click(object sender, RoutedEventArgs e)
        {
            //List<string> files = CreateFilesList(Settings.Default.Serie, true);
            List<string> files = CreateFilesList(Settings.Default.SerieDl, false);
            FilesTreatment(files);
        }

        private void Menu_FindSrt_Click(object sender, RoutedEventArgs e)
        {
            if (Settings.Default.SubDl == null)
            {
                ////////
            }

            if (Settings.Default.SubDl != null && Directory.Exists(Settings.Default.SubDl))
            {
                List<string> files = CreateFilesList(Settings.Default.SubDl, true, false);
                FilesTreatment(files);
            }
        }

        private void Menu_Consolidation_Click(object sender, RoutedEventArgs e)
        {
            //Consolidation();
        }

        private void Menu_GetFollowed_Click(object sender, RoutedEventArgs e)
        {
            Followed();
        }

        private void Menu_GetImages_Click(object sender, RoutedEventArgs e)
        {
            Parallel.ForEach(seriesContext.Series, s =>
            {
                //foreach (var s in seriesContext.Series)
                //{
                s.ImagePath = new Tvdb().LoadBanner(s.IdTvdb.Value, true);
            });


            //}

            ListBoxImage.Items.Refresh();
            seriesContext.SaveChanges();
        }

        private async void Menu_GetSeriesInfo_Click(object sender, RoutedEventArgs e)
        {
            Tvdb tvdb = new Tvdb();

            Parallel.ForEach(seriesContext.Series, s =>
            {
                //foreach (Series s in seriesContext.Series.Local)
                //{


                tvdb.UpdateSerieData(s);


                //}
            });

            seriesContext.SaveChanges();
            await seriesContext.Series.LoadAsync();

        }

        private void Menu_GetSerie_Click(object sender, RoutedEventArgs e)
        {
            Tvdb tvdb = new Tvdb();
            tvdb.GetFullSeries();
        }

        private void Menu_GetSubDirectory_Click(object sender, RoutedEventArgs e)
        {
            List<string> files = new List<string>();
            SearchOption searchOption = SearchOption.TopDirectoryOnly;

            //Cast pour savoir si c'est un cheminq qui renvoie vers un dossier
            if (Directory.Exists("D:\\Downloads\\"))
            {
                //Boucle pour ajouté tous les files SRT et AVI dans la liste
                Parallel.ForEach(Directory.GetFiles("D:\\Downloads\\", "*", searchOption), item =>
                //foreach (string item in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
                {
                    string ext = Path.GetExtension(item);
                    if (ext == ".srt")
                        files.Add(item);
                });
            }
            FilesTreatment(files);
        }

        private async void Menu_ShowMissedEpisodes_Click(object sender, RoutedEventArgs e)
        {
            //seriesContext.Episodes.Load();

            //var missedepisodes = from ep in seriesContext.Episodes.Local where ep.AddDate == null select ep;      

            var missedEpisodes = await seriesContext.Episodes.Where(ep => ep.FilePath == null).Where(ep => ep.AirDate <= DateTime.Now).ToListAsync();

            MissingEpisodes me = new MissingEpisodes(missedEpisodes);
            me.ShowDialog();
        }

        private void Menu_MissedSubsSelected_Click(object sender, RoutedEventArgs e)
        {
            foreach (Episodes episode in DataGridEpisodes.SelectedItems)
            {
                if (episode.Name != null)
                {
                    string nomEpisode = episode.Name != null ? Regex.Replace(episode.Name, " ", "_") : "test";
                    string link = "http://www.addic7ed.com/serie/" + Regex.Replace(episode.Saisons.Series.Name, " ", "_") + "/" + episode.Saisons.Num + "/" + episode.Num + "/" + nomEpisode;
                    Process.Start(link);
                }
            }
        }

        private void Menu_Preference_Click(object sender, RoutedEventArgs e)
        {
            Preference wdw = new Preference();
            wdw.ShowDialog();
            if (wdw.Consolidation)
                //Consolidation();

                if (wdw.PathUpdated)
                {
                }
        }
        private void Menu_Save_Click(object sender, RoutedEventArgs e)
        {
            seriesContext.SaveChanges();
        }

        private void Menu_UpdateCache_Click(object sender, RoutedEventArgs e)
        {
            new Tvdb().UpdateCache();
        }
        #endregion Menu

        #region Menu Contextuel Serie (image/classique)

        private void MCSerie_addic7ed_Click(object sender, RoutedEventArgs e)
        {
            //prendre le nom de la serie puis créer le lien addicted
        }

        private void MCSerie_AddPlayList_Click(object sender, RoutedEventArgs e)
        {
            Series s = ((ListBox)sender).SelectedItem as Series;
            if (s != null)
            {
                seriesContext.Episodes.Load();
                var ep = from b in seriesContext.Episodes.Local where b.Saisons.SeriesID == s.ID select b;
                if (m_playListEpisodesCollection != null)
                    m_playListEpisodesCollection = new ObservableCollection<Episodes>();
                m_playListEpisodesCollection.Concat(ep);
            }
        }

        private void MCSerie_AnnuleVue_Click(object sender, RoutedEventArgs e)
        {
            Series s = ((ListBox)sender).SelectedItem as Series;
            if (s != null)
            {
                seriesContext.Episodes.Load();
                var eps = from b in seriesContext.Episodes.Local where b.Saisons.SeriesID == s.ID select b;

                foreach (var ep in eps)
                {
                    ep.Saw = false;
                }
                seriesContext.SaveChanges();
            }
        }

        private void MCSerie_GetInfo_Click(object sender, RoutedEventArgs e)
        {
            //prendre le nom de la serie et recup tout les episodes
        }

        private void MCSerie_LireAll_Click(object sender, RoutedEventArgs e)
        {
            Series s = ((ListBox)sender).SelectedItem as Series;
            if (s != null)
            {
                seriesContext.Episodes.Load();
                var eps = from b in seriesContext.Episodes.Local where b.Saisons.SeriesID == s.ID select b;

                string path = GeneratePlayListFile(eps.ToList<Episodes>());
                Process.Start(path);
            }
        }
        private void MCSerie_OuvrirExplorer_Click(object sender, RoutedEventArgs e)
        {
            MenuItem mnu = sender as MenuItem;
            ListBoxItem lb = null;
            if (mnu != null)
            {
                lb = ((ContextMenu)mnu.Parent).PlacementTarget as ListBoxItem;
            }

            Series s = lb.Content as Series;
            if (s != null)
            {
                string path = Settings.Default.Serie + "\\" + s.Name;
                if (Directory.Exists(path))
                    Process.Start(path);
                else
                {
                    //cherche le chemin puis l'enregistrer dans la bdd
                    System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();

                    dlg.Description = "Sélectionner un dossier";
                    if (Directory.Exists(Settings.Default.Serie))
                        dlg.SelectedPath = Settings.Default.Serie;
                    else
                        dlg.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);

                    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        path = dlg.SelectedPath;
                    }
                    else
                        System.Windows.Forms.MessageBox.Show("Choisissez un dossier");

                    s.Path = path;

                    seriesContext.SaveChanges();
                }
            }
        }

        private void MCSerie_Supprimer_Click(object sender, RoutedEventArgs e)
        {
            //prendre le nom de la serie puis recup le dossier et tout supprimé avec boite de confirmation
            //supprime juste la serie de la bdd tempo

            MenuItem mnu = sender as MenuItem;
            //ListBox lb = null;
            Series s = null;
            if (mnu != null)
            {
                //lb = ((ContextMenu)mnu.Parent).PlacementTarget as ListBox;
                ListBoxItem item = ((ContextMenu)mnu.Parent).PlacementTarget as ListBoxItem;
                s = item.Content as Series;
            }

            //Obtient la serie sur laquel est cliqué le menu
            //Series s = lb.SelectedItem as Series;
            if (s != null)
            {
                foreach (Saisons sa in s.Saisons) // supression Episodes pour chaque saison
                {
                    seriesContext.Episodes.RemoveRange(sa.Episodes);
                }

                seriesContext.Saisons.RemoveRange(s.Saisons);//suppression des saisons
                seriesContext.Series.Remove(s); // suppression de la serie
            }

            // ListBoxImage.Items.Remove(lb);

            seriesContext.SaveChanges();
            ListBoxImage.DataContext = null;
            ListBoxImage.DataContext = seriesContext.Series.Local.OrderBy(i => i.Name);
        }

        private void MCSerie_tvdb_Click(object sender, RoutedEventArgs e)
        {
            Series serie = ((ListBox)sender).SelectedItem as Series;

            string link = "http://www.";

            if (serie != null) //c'est une serie
            {
                link += "thetvdb.com/?tab=series&id=" + serie.IdTvdb;
                Process.Start(link);
            }
            else //sinon c'est une saison
            {
                Saisons saison = ((ListBox)sender).SelectedItem as Saisons;
                if (saison != null) // si pas nul
                {
                    int i = new Tvdb().GetSaisonId(saison.Series.IdTvdb, saison.Num);
                    link += "thetvdb.com/?tab=season&seriesid=" + saison.Series.IdTvdb + "&seasonid=" + i + "&lid=7";
                    Process.Start(link);
                }
            }
        }

        private async void MCSerie_Vue_Click(object sender, RoutedEventArgs e)
        {
            MenuItem mnu = sender as MenuItem;
            ListBox l = null;

            if (mnu != null)
            {
                l = ((ContextMenu)mnu.Parent).PlacementTarget as ListBox;
            }

            if (l == ListBoxImage)
            {
                Series s = l.SelectedItem as Series;
                if (s != null)
                {
                    foreach (Saisons saison in s.Saisons)
                    {
                        foreach (Episodes ep in saison.Episodes)
                        {
                            ep.Saw = true;
                        }
                    }

                    seriesContext.SaveChanges();
                }
            }

            await SetNumberOfNoViewedEpisodes();
        }
        #endregion Menu Contextuel Serie (image/classique)

        #region Menu Contextuel DG

        private void MenuContext_addic7ed_Click(object sender, RoutedEventArgs e)
        {
            Episodes episode = DataGridEpisodes.SelectedItem as Episodes;

            string link = "http://www.";

            if (episode != null)
            {
                link += "addic7ed.com/serie/" + Regex.Replace(episode.Saisons.Series.Name, " ", "_") + "/" + episode.Saisons.Num + "/" + episode.Num + "/" + Regex.Replace(episode.Name, " ", "_");
                Process.Start(link);
            }
        }

        private void MenuContext_AddPlayList_Click(object sender, RoutedEventArgs e)
        {
            AddPlayList(DataGridEpisodes.SelectedItems);
        }

        private void MenuContext_AnnuleVisionner_Click(object sender, RoutedEventArgs e)
        {
            foreach (Episodes episode in DataGridEpisodes.SelectedItems)
            {
                episode.Saw = false;
                seriesContext.SaveChanges();
            }

            DataGridEpisodes.Items.Refresh();
        }

        private void MenuContext_GetInfo_Click(object sender, RoutedEventArgs e)
        {
            if (m_bwChercherNom == null)
            {
                //IList<Episodes> episode = DataGridEpisodes.SelectedItems as IList<Episodes>;

                List<Episodes> episodes = new List<Episodes>();

                foreach (Episodes episode in DataGridEpisodes.SelectedItems)
                {
                    episodes.Add(episode);
                }
                if (episodes != null)
                {
                    m_bwChercherNom = new BackgroundWorker();
                    InitializeBackgroundWorker(m_bwChercherNom, 2);
                    m_bwChercherNom.RunWorkerAsync(episodes);
                    m_bwChercherNom.Dispose();
                }
            }
        }

        private void MenuContext_Lire_Click(object sender, RoutedEventArgs e)
        {
            WatchEpisode(DataGridEpisodes.SelectedItem as Episodes);
        }
        private void MenuContext_Modifier_Click(object sender, RoutedEventArgs e)
        {
            Episodes ep = DataGridEpisodes.SelectedItem as Episodes;

            EpisodesTempo episode = new EpisodesTempo(ep.Saisons.Num, ep.Num, ep.Saisons.Series.Name, ep.FilePath);

            //ouvre la fenetre de modif
            EditEpisodeWindow wdw = new EditEpisodeWindow(episode);
            wdw.ShowDialog();

            historiqueTb.Text += Environment.NewLine;

            //si il y a modification on les applique
            if (wdw.DialogResult.Value == true)
            {
                ep.Saisons.Series.Name = episode.Serie;
                ep.Saisons.Num = episode.Saison;
                ep.Num = episode.Episode;

                Tvdb tvdb = new Tvdb();
                tvdb.UpdateEpisodeData(ep);

                //renomage du fichier en conséquence :
                try
                {
                    string newPath = ep.CheminFichierEpisode();
                    if (newPath != null)
                    {
                        File.Move(ep.FilePath, newPath);
                        ep.FilePath = newPath;

                        historiqueTb.Text += " ----> " + ep.ToString();
                    }
                    else

                        historiqueTb.Text += " ----> Non déplacé car le nouveau chemin est null";
                }
                catch (Exception ex)
                {
                    historiqueTb.Text += " ----> Non déplacé car :" + ex.ToString();
                }

                historiqueTb.Text += " - modifié";
            }
            else
                historiqueTb.Text += ep.FilePath + " - non modifié";
        }

        private void MenuContext_OuvrirExplorer_Click(object sender, RoutedEventArgs e)
        {
            Episodes episode = DataGridEpisodes.SelectedItem as Episodes;

            if (episode != null)
            {
                string directoryPath = Path.GetDirectoryName(episode.FilePath);
                if (Directory.Exists(directoryPath))
                    Process.Start(directoryPath);
            }
            //if (episode != null && File.Exists(episode.FilePath))
            //    Process.Start(Path.GetDirectoryName(episode.FilePath));
        }

        private void MenuContext_ssubs_Click(object sender, RoutedEventArgs e)
        {
            Episodes episode = DataGridEpisodes.SelectedItem as Episodes;

            string link = "http://www.";

            if (episode.Name != null)
            {
                link += "seriessub.com/sous-titres/" + episode.Saisons.Series.Name + "/saison_" + episode.Saisons.Num;
                Process.Start(link);
            }
        }

        private void MenuContext_Supprimer_Click(object sender, RoutedEventArgs e)
        {
            // Configure the message box to be displayed
            string messageBoxText = "Voulez-vous envoyer le fichier à la corbeille ?";
            string caption = "Confirmation";
            MessageBoxButton button = MessageBoxButton.YesNoCancel;
            MessageBoxImage icon = MessageBoxImage.Warning;
            // Display message box
            //MessageBox.Show(messageBoxText, caption, button, icon);
            // Display message box
            MessageBoxResult result = MessageBox.Show(messageBoxText, caption, button, icon);

            // Process message box results
            switch (result)
            {
                case MessageBoxResult.Yes:
                    // User pressed Yes button
                    foreach (Episodes episode in DataGridEpisodes.SelectedItems)
                    {
                        if (File.Exists(episode.FilePath))
                            try
                            {
                                File.Delete(episode.FilePath);
                                if (episode.Sub == true)
                                    File.Delete(episode.SubPath);

                                seriesContext.Episodes.Remove(episode);
                                seriesContext.SaveChanges();

                                historiqueTb.Text += episode.FilePath + " -> supprimé";
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.ToString());
                            }
                        else
                            MessageBox.Show("Fichier introuvable");
                    }
                    break;

                case MessageBoxResult.No:
                    // User pressed No button
                    foreach (Episodes episode in DataGridEpisodes.SelectedItems)
                    {
                        seriesContext.Episodes.Remove(episode);
                        seriesContext.SaveChanges();
                    }
                    break;

                case MessageBoxResult.Cancel:
                    // User pressed Cancel button
                    // Nothing
                    break;
            }
            UpdateSizeInStatutBar();
        }

        private void MenuContext_SupprimerSousTitre_Click(object sender, RoutedEventArgs e)
        {
            //Episodes episode = DataGridEpisodes.SelectedItem as Episodes;

            if (DataGridEpisodes.SelectedItems != null)
            {
                // Configure the message box to be displayed
                string messageBoxText = "Voulez-vous envoyer le fichier à la corbeille ?";
                string caption = "Confirmation";
                MessageBoxButton button = MessageBoxButton.YesNoCancel;
                MessageBoxImage icon = MessageBoxImage.Warning;
                MessageBoxResult result = MessageBox.Show(messageBoxText, caption, button, icon);
                // Process message box results
                switch (result)
                {
                    case MessageBoxResult.Yes:
                        // User pressed Yes button
                        foreach (Episodes episode in DataGridEpisodes.SelectedItems)
                        {
                            if (File.Exists(episode.SubPath))
                                try
                                {
                                    File.Delete(episode.SubPath);
                                    //if (episode.Sub == true)
                                    //    File.Delete(episode.SubPath);*
                                    episode.Sub = false;

                                    historiqueTb.Text += "[SOUS TITRE] - " + episode.SubPath + " -> supprimé";
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.ToString());
                                }
                            else
                                MessageBox.Show("Fichier introuvable");
                        }
                        break;

                    case MessageBoxResult.No:
                        // User pressed No button
                        //foreach (Episodes episode in listeEpisodes)
                        //{
                        //    seriesContext.Episodes.Remove(episode);
                        //    seriesContext.SaveChanges();
                        //}
                        break;

                    case MessageBoxResult.Cancel:
                        // User pressed Cancel button
                        // Nothing
                        break;
                }
            }
        }

        private void MenuContext_tvdb_Click(object sender, RoutedEventArgs e)
        {
            Episodes episode = DataGridEpisodes.SelectedItem as Episodes;

            string link = "http://www.";

            MenuItem mi = sender as MenuItem;

            if (episode.Name != null)
            {
                link += "thetvdb.com/?tab=episode&seriesid=" + episode.Saisons.Series.IdTvdb + "&seasonid=" + episode.Saisons.IdTvdb + "&id=" + episode.IdTvdb + "&lid=17";
                Process.Start(link);
            }
        }
        private async void MenuContext_Visionner_Click(object sender, RoutedEventArgs e)
        {
            foreach (Episodes episode in DataGridEpisodes.SelectedItems)
            {
                episode.Saw = true;
                seriesContext.SaveChanges();
            }

            await SetNumberOfNoViewedEpisodes();
            DataGridEpisodes.Items.Refresh();
        }

        #endregion Menu Contextuel DG

        #region Click

        public bool ShowFollowed(object de)
        {
            Series se = de as Series;
            //Return members whose Orders have not been filled
            return se.Followed;
        }

        private void Btn_AddPlayList_Click(object sender, RoutedEventArgs e)
        {
            AddPlayList(DataGridEpisodes.SelectedItems);
        }

        private void CheckBoxShowFollowed_Checked(object sender, RoutedEventArgs e)
        {
            if (ListBoxImage != null)
                ListBoxImage.Items.Filter = new Predicate<object>(ShowFollowed);
        }

        private void CheckBoxShowFollowed_Unchecked(object sender, RoutedEventArgs e)
        {
            ListBoxImage.Items.Filter = null;
        }

        private void detailSerieBtn_Click(object sender, RoutedEventArgs e)
        {
            if (detailSerieBtn.IsChecked == true)
                ShowImageAndDetail(true);
            else
                ShowImageAndDetail(false);
        }

        private void ListBoxClassique_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            //toogleboutton
            recentBtn.IsChecked = nonVueBtn.IsChecked = seriesBtn.IsChecked = false;
            toutBtn.IsChecked = true;

            ListBoxImage.Visibility = Visibility.Collapsed;
            ListBoxSaison.Visibility = Visibility.Visible;
        }

        #region listbox
        private void ListBoxClassique_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
        }
        private void ListBoxImage_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            //toogleboutton
            recentBtn.IsChecked = nonVueBtn.IsChecked = seriesBtn.IsChecked = false;
            toutBtn.IsChecked = true;

            Series actualSerie = ((ListBox)sender).SelectedItem as Series; //obtient la serie
            //QuadraticBezierSegment//
            if (actualSerie == null)
                return; //si pas de serie n arrete

            DockPanelVueDetaillee.DataContext = actualSerie.Saisons.OrderBy(s => s.Num);

            //créer le binding
            Binding b = new Binding();
            b.Path = new PropertyPath("Episodes");
            b.Source = DockPanelVueDetaillee.DataContext; // ou new ViewModel()
            DataGridEpisodes.SetBinding(DataGrid.ItemsSourceProperty, b);
            DataGridEpisodes.Items.SortDescriptions.Add(new SortDescription("Num", ListSortDirection.Ascending)); //sort

            //set datacontext pour les detail
            GridDetailSerie.DataContext = actualSerie;

            ListBoxImage.Visibility = Visibility.Collapsed;
            DockPanelVueDetaillee.Visibility = Visibility.Visible;

            ListBoxSaison.SelectedIndex = 0;
            //nom de la serie
            TextBlockSerieName.Text = actualSerie.Name + " - Saison " + actualSerie.Saisons.First().Num;
            //on enleve la selection d'un item
        }
        private void ListBoxSaison_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            Series actualSerie = ListBoxSaison.SelectedItem as Series;

            if (actualSerie != null) //si c'est une serie
            {
                //Series actualSerie = ListBoxSaison.SelectedItem as Series; //obtient la serie
                //actualSerie.Saisons.OrderBy(s => s.Num);
                DockPanelVueDetaillee.DataContext = actualSerie.Saisons.OrderBy(s => s.Num);

                Binding b = new Binding();
                b.Path = new PropertyPath("Episodes");
                b.Source = DockPanelVueDetaillee.DataContext; // ou new ViewModel()

                DataGridEpisodes.SetBinding(DataGrid.ItemsSourceProperty, b);
                DataGridEpisodes.Items.SortDescriptions.Add(new SortDescription("Num", ListSortDirection.Ascending));
                GridDetailSerie.DataContext = actualSerie;

                ListBoxImage.Visibility = Visibility.Collapsed;
                DockPanelVueDetaillee.Visibility = Visibility.Visible;

                //nom de la serie
                TextBlockSerieName.Text = actualSerie.Name + " - Saison " + actualSerie.Saisons.First().Num;
                //on enleve la selection d'un item
                ListBoxSaison.SelectedItem = 0;
            }
            else
            { }
        }
        private void ListBoxSaison_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (ListBoxSaison.IsMouseOver) //on verifie que c'est l'utilisateur qui a declanché ceci
                if (ListBoxSaison.SelectedItem != null) //episode => saison
                {
                    var test = ((ListBox)sender).SelectedItem.GetType(); //on recupere le type d'eleemnt

                    if (test.BaseType.FullName == "Serietheque.Saisons") //on veririe que c'est une saison
                    {
                        Saisons actualSaison = ((ListBox)sender).SelectedItem as Saisons; //recup la saison

                        if (actualSaison != null)
                        {
                            DataGridEpisodes.Items.SortDescriptions.Clear();
                            DataGridEpisodes.Items.SortDescriptions.Add(new SortDescription("Num", ListSortDirection.Ascending));
                            TextBlockSerieName.Text = actualSaison.Series.Name + " - Saison " + actualSaison.Num.ToString().ToUpper(); //noml de la serie en haut avec saison
                            GridDetailSerie.DataContext = actualSaison.Series;//bind des detail
                        }
                    }
                    else if (test.BaseType.FullName == "Serietheque.Series") //ou une serie
                    {
                        Series actualSerie = ((ListBox)sender).SelectedItem as Series;//recup de la serie

                        if (actualSerie != null)//verifi que la serie est valide
                        {
                            TextBlockSerieName.Text = actualSerie.Name;//nom de la serie en haut
                            GridDetailSerie.DataContext = actualSerie;//bind des detail


                            seriesContext.Episodes.Load();//charge les episodes

                            DataGridEpisodes.ItemsSource = seriesContext.Episodes.Local.Where(x => x.Saisons.Series.ID == actualSerie.ID).OrderBy(x => x.Saisons.Num).OrderBy(x => x.Num);
                        }
                    }
                }
        }
        private void retourSeriesClassiqueBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllEpisodes();
        }
        #endregion listbox
        private void StopBtn_Click(object sender, RoutedEventArgs e)
        {
            if (m_bwAjoutBiblio != null)
                m_bwAjoutBiblio.CancelAsync();
            else if (m_bwConsolidation != null)
                m_bwConsolidation.CancelAsync();
        }

        private void Vue_nonvisioBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowFilteredEpisodes();

            if (nonVueBtn.IsChecked == true)
            {
                seriesBtn.IsChecked = toutBtn.IsChecked = recentBtn.IsChecked = false;

                DataGridEpisodes.ItemsSource = GetEpisodesNonVue();

                ShowNumbersEpisodes();

                ListBoxSaison.SelectedItem = null;
            }
            else
            {
                toutBtn.IsChecked = true;

                DataGridEpisodes.Items.Refresh();
            }
        }

        private async void Vue_recentBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowFilteredEpisodes();

            if (recentBtn.IsChecked == true)
            {
                //UI
                seriesBtn.IsChecked =
                toutBtn.IsChecked =
                nonVueBtn.IsChecked = false; //decheck les tooglebtn

                //BD
                //seriesContext.Episodes.Load(); // charge les episodes
                DataGridEpisodes.ItemsSource = GetEpisodesRecent();

                //Async task


                //UI
                ShowNumbersEpisodes();

                ListBoxSaison.SelectedItem = null;
            }
            else
            {
                toutBtn.IsChecked = true;
                DataGridEpisodes.Items.Refresh();
            }

            await SetNumberOfRecentEpisodes();
        }

        private async Task SetNumberOfRecentEpisodes()
        {
            DateTime dt = DateTime.Now;
            dt.Subtract(new TimeSpan(7, 0, 0, 0));

            List<Episodes> le = await seriesContext.Episodes.Where(x => x.AirDate.Value.CompareTo(dt) == 1 && x.AirDate.Value.CompareTo(DateTime.Now) == -1).ToListAsync();

            int i = le.Count();

            recentBtn.Content = "récent (" + i + ")";

            //throw new NotImplementedException();
            //throw new NotImplementedException();

        }

        private async Task SetNumberOfNoViewedEpisodes()
        {
            List<Episodes> le = await seriesContext.Episodes.Where(x => x.Saw == false).ToListAsync();

            int i = le.Count();

            nonVueBtn.Content = "non Vue (" + i + ")";
            //throw new NotImplementedException();
        }

        private void ShowNumbersEpisodes()
        {
            //if (DataGridEpisodes.Items.Count == 0)
            //    TextBlockSerieName.Text = "Aucun épisode récent";
            //else if (DataGridEpisodes.Items.Count == 1)
            //    TextBlockSerieName.Text = DataGridEpisodes.Items.Count + " Epsiode";
            //else
            //    TextBlockSerieName.Text = DataGridEpisodes.Items.Count + " Epsiodes";


        }

        private IEnumerable<Episodes> GetEpisodesRecent()
        {
            return from ep in seriesContext.Episodes.Local
                   where (ep.AirDate != null && (ep.AirDate.Value.DayOfYear > DateTime.Now.DayOfYear - 7) && ep.AirDate.Value.DayOfYear < DateTime.Now.DayOfYear + 7 && ep.AirDate.Value.Year == DateTime.Now.Year)
                   select ep;

            // return listeEpisodesRecent;
        }

        private IEnumerable<Episodes> GetEpisodesNonVue()
        {
            return seriesContext.Episodes.Local.Where(x => x.Saw == false).OrderBy(x => x.Saisons.Num).ThenBy(x => x.Num);
        }


        private void Vue_seriesBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowSeriesOnly();
        }

        private void Vue_toutBtn_Click(object sender, RoutedEventArgs e)
        {
            ShowAllEpisodes();

            ListBoxSaison.SelectedItem = null;

            toutBtn.IsChecked = true;
            recentBtn.IsChecked = false;
            nonVueBtn.IsChecked = false;
            seriesBtn.IsChecked = false;
        }
        #endregion Click

        #region Playlist

        private void ListBoxPlayListItem_Drop(object sender, DragEventArgs e)
        {
            Episodes droppedData = e.Data.GetData(typeof(Episodes)) as Episodes;
            Episodes target = ((ListBoxItem)(sender)).DataContext as Episodes;

            int removedIdx = ListBoxPlayList.Items.IndexOf(droppedData);
            int targetIdx = ListBoxPlayList.Items.IndexOf(target);

            if ((removedIdx < targetIdx) && (removedIdx > 0))
            {
                m_playListEpisodesCollection.Insert(targetIdx + 1, droppedData);
                m_playListEpisodesCollection.RemoveAt(removedIdx);
            }
            else
            {
                int remIdx = removedIdx + 1;
                if (m_playListEpisodesCollection.Count + 1 > remIdx)
                {
                    m_playListEpisodesCollection.Insert(targetIdx, droppedData);
                    m_playListEpisodesCollection.RemoveAt(remIdx);
                }
            }
        }

        private void ListBoxPlayListItem_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (sender is ListBoxItem && e.LeftButton == MouseButtonState.Pressed)
            {
                ListBoxItem draggedItem = sender as ListBoxItem;
                DragDrop.DoDragDrop(draggedItem, draggedItem.DataContext, DragDropEffects.Move);
                draggedItem.IsSelected = true;
            }
        }

        private void PlayListClear_Click(object sender, RoutedEventArgs e)
        {
            m_playListEpisodesCollection.Clear();
        }

        private void PlayListMenu_Delete_Click(object sender, RoutedEventArgs e)
        {
            m_playListEpisodesCollection.Remove((Episodes)ListBoxPlayList.SelectedItem);
        }

        private void PlayListPlay_Click(object sender, RoutedEventArgs e)
        {
            string path = GeneratePlayListFile(m_playListEpisodesCollection);
            Process.Start(path);
        }
        #endregion Playlist

        #region datagridEpisode

        #region Datagrid Divers

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (objEmpToEdit == null)
            {
                MessageBox.Show("Cannot delete the blank Entry");
            }

            else
            {
                seriesContext.Episodes.Remove(objEmpToEdit);
                seriesContext.SaveChanges();
                DataGridEpisodes.Items.Refresh();
                MessageBox.Show("Record Deleted..");
            }
        }

        private void btnUpdate_Click(object sender, RoutedEventArgs e)
        {
            //DataGridEpisodes.Columns[2].IsReadOnly = false;

            //DataGridEpisodes.Columns[3].IsReadOnly = false;
        }

        private void dgEpisode_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            WatchEpisode(DataGridEpisodes.SelectedItem as Episodes);
        }

        private void dgEpisode_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Episodes ep = ((DataGrid)sender).SelectedItem as Episodes;
            if (ep is Episodes)
            {
                Series s = ep.Saisons.Series;
                Binding b = new Binding();
                b.Path = new PropertyPath("Episodes");
                b.Source = DockPanelVueDetaillee.DataContext; // ou new ViewModel()

                //DataGridEpisodes.SetBinding(DataGrid.ItemsSourceProperty, b);
                //DataGridEpisodes.Items.SortDescriptions.Add(new SortDescription("Num", ListSortDirection.Ascending));
                GridDetailSerie.DataContext = s;

                
            }

        }

        private void dgEpisode_Sorting(object sender, DataGridSortingEventArgs e)
        {
            //if (e.Column.SortMemberPath == "NomSerie" || e.Column.SortMemberPath == "NumEpisode")
            //{
            //    e.Handled = true;

            //    if (m_ascSortDgEpisode)
            //        m_filtreViewDgEpisode.CustomSort = new CustomSortEpisodeDes();
            //    else
            //        m_filtreViewDgEpisode.CustomSort = new CustomSortAsc();

            //    m_ascSortDgEpisode = m_ascSortDgEpisode ? false : true;
            //}
        }
        #endregion Datagrid Divers

        #endregion datagridEpisode

        #region Drop

        private void window_Drop(object sender, DragEventArgs e)
        {
            //Si c'est des files de déposer
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                //files = new List<string>();
                //On definie l'effet
                e.Effects = DragDropEffects.Copy;

                //on récupére la liste des _paths déposé que l'on passe dans CreateFilesList pour récupéré vidéo et sous titre
                List<string> files = CreateFilesList((string[])e.Data.GetData(DataFormats.FileDrop, false));

                //on traite tout ca
                //files = file.
                FilesTreatment(files);
            }
        }

        #endregion Drop
        #endregion Evenenemnt

        #region Méthode

        public static Color CalculateAverageColor(BitmapSource source)
        {
            if (source != null)
            {
                if (source.Format.BitsPerPixel != 32)
                    throw new ApplicationException("expected 32bit image");

                Color cl;
                System.Windows.Size sz = new System.Windows.Size(source.PixelWidth, source.PixelHeight);

                //read bitmap
                int pixelsSz = (int)sz.Width * (int)sz.Height * (source.Format.BitsPerPixel / 8);
                int stride = ((int)sz.Width * source.Format.BitsPerPixel + 7) / 8;

                byte[] pixels = new byte[pixelsSz];
                source.CopyPixels(pixels, stride, 0);

                //find the average color for the image
                const int alphaThershold = 10;
                UInt64 r, g, b, a; r = g = b = a = 0;
                UInt64 pixelCount = 0;

                for (int y = 0; y < sz.Height; y++)
                {
                    for (int x = 0; x < sz.Width; x++)
                    {
                        int index = (int)((y * sz.Width) + x) * 4;
                        if (pixels[index + 3] <= alphaThershold) //ignore transparent
                            continue;

                        pixelCount++;
                        a += pixels[index + 3];
                        r += pixels[index + 2];
                        g += pixels[index + 1];
                        b += pixels[index];
                    }
                }

                //average color result
                cl = Color.FromArgb((byte)(a / pixelCount),
                                    (byte)(r / pixelCount),
                                    (byte)(g / pixelCount),
                                    (byte)(b / pixelCount));

                return cl;
            }
            return Colors.AliceBlue;
        }


        //Conversition octet => MO
        [DllImport("shlwapi")]
        public static extern int StrFormatByteSize64(long qdw, StringBuilder pszBuf, uint cchBuf);

        /// <summary>
        /// Undoes any pending updates
        /// </summary>
        public void UndoUpdates(DbContext dbContext)
        {
            //Get list of entities that are marked as modified
            List<DbEntityEntry> modifiedEntityList =
                dbContext.ChangeTracker.Entries().Where(x => x.State == EntityState.Modified).ToList();

            foreach (DbEntityEntry entity in modifiedEntityList)
            {
                DbPropertyValues propertyValues = entity.OriginalValues;
                foreach (String propertyName in propertyValues.PropertyNames)
                {
                    //Replace current values with original values
                    PropertyInfo property = entity.Entity.GetType().GetProperty(propertyName);
                    property.SetValue(entity.Entity, propertyValues[propertyName]);
                }
            }
        }

        private static void AddConnectionStrings()
        {
            // Get the count of the connection strings.
            int connStrCnt = ConfigurationManager.ConnectionStrings.Count;

            // Define the string name.
            string csName = "SeriesEntities" + connStrCnt.ToString();

            // Get the configuration file.
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            // Add the connection string.
            ConnectionStringsSection csSection = config.ConnectionStrings;
            csSection.ConnectionStrings.Remove("SeriesEntities");

            //csSection.ConnectionStrings.Add(new ConnectionStringSettings("SeriesEntities", "metadata=res://*/Model2.csdl|res://*/Model2.ssdl|res://*/Model2.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(LocalDB)\\v11.0;attachdbfilename=" + Settings.Default.Cache + "\\bdd.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework&quot;"));
            csSection.ConnectionStrings.Add(new ConnectionStringSettings("SeriesEntities", @"metadata=res://*/Model2.csdl|res://*/Model2.ssdl|res://*/Model2.msl;provider=System.Data.SqlClient;provider connection string=';data source=(LocalDB)\v11.0;attachdbfilename=" + Settings.Default.Cache + "\\bdd.mdf;integrated security=True;connect timeout=30;MultipleActiveResultSets=True;App=EntityFramework';", "System.Data.EntityClient"));

            // Save the configuration file.
            config.Save(ConfigurationSaveMode.Modified, true);
            config.Save();
        }

        /// <summary>
        /// Génere la liste des files video de plusieur repertoire/chemin
        /// </summary>
        /// <param name="_paths">repertoires/fichier</param>
        /// <param name="_allDirectory">rechercher dans les sous repertoire ou non (default = true)</param>
        /// <returns>liste des files video</returns>
        private static List<string> CreateFilesList(string[] _paths, bool _allDirectory = true)
        {
            //liste des fichier
            List<string> files = new List<string>();
            //definition du cherche option selon les parametre
            SearchOption searchOption = _allDirectory ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

            //boucle parralele pour chercher tout les video
            Parallel.ForEach(_paths, path =>
            {
                //Cast pour savoir si c'est un cheminq qui renvoie vers un dossier
                if (Directory.Exists(path))
                {
                    //Boucle pour ajouté tous les files SRT et AVI dans la liste
                    Parallel.ForEach(Directory.GetFiles(path, "*", searchOption), item =>
                    {
                        string ext = Path.GetExtension(item);
                        if (ext == ".srt" || ext == ".avi" || ext == ".mkv" || ext == ".mp4")
                            files.Add(item);
                    });
                }
                //ou un fichier
                else if (File.Exists(path))
                {
                    string ext = Path.GetExtension(path);
                    if (ext == ".srt" || ext == ".avi" || ext == ".mkv" || ext == ".mp4")
                        files.Add(path);
                }
            });
            return files; // List<string>
        }

        /// <summary>
        /// Génere la liste des files video d'un repertoire
        /// </summary>
        /// <param name="_directoryPath">repertoires/fichier</param>
        /// <param name="_allDirectory">rechercher dans les sous repertoire ou non (default = true)</param>
        /// <returns>liste des files video</returns>
        private static List<string> CreateFilesList(string _directoryPath, bool _allDirectory = true)
        {
            List<string> files = new List<string>();
            SearchOption searchOption = _allDirectory ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

            //Cast pour savoir si c'est un cheminq qui renvoie vers un dossier
            if (Directory.Exists(_directoryPath))
            {
                //Boucle pour ajouté tous les files SRT et AVI dans la liste
                Parallel.ForEach(Directory.GetFiles(_directoryPath, "*", searchOption), item =>
                //foreach (string item in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
                {
                    string ext = Path.GetExtension(item);
                    if (ext == ".avi" || ext == ".mkv" || ext == ".mp4")
                        files.Add(item);
                });
            }

            return files; // List<string>
        }

        /// <summary>
        /// Génere la liste des files video d'un repertoire
        /// </summary>
        /// <param name="_directoryPath">repertoires/fichier</param>
        /// <param name="_allDirectory">rechercher dans les sous repertoire ou non (default = true)</param>
        /// <param name="_sub">cherche pour des sous titres</param>
        /// <returns>liste des files video</returns>
        private static List<string> CreateFilesList(string _directoryPath, bool _sub, bool _allDirectory = true)
        {
            List<string> files = new List<string>();
            SearchOption searchOption = _allDirectory ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

            //Cast pour savoir si c'est un cheminq qui renvoie vers un dossier
            if (Directory.Exists(_directoryPath))
            {
                //Boucle pour ajouté tous les files SRT et AVI dans la liste
                Parallel.ForEach(Directory.GetFiles(_directoryPath, "*", searchOption), item =>
                //foreach (string item in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
                {
                    string ext = Path.GetExtension(item);
                    if (ext == ".srt")
                        files.Add(item);
                });
            }

            return files; // List<string>
        }

        private void AddPlayList(IList _listEp)
        {
            if (m_playListEpisodesCollection == null)
                m_playListEpisodesCollection = new ObservableCollection<Episodes>();

            foreach (Episodes episode in _listEp)
            {
                m_playListEpisodesCollection.Add(episode);
            }

            ListBoxPlayList.ItemsSource = PlayListEpisodesCollection;
        }

        private string GeneratePlayListFile(IList<Episodes> list)
        {
            string path = Settings.Default.Serie + "\\playlist.m3u";

            if (File.Exists(path))
                File.Delete(path);

            using (StreamWriter sr = new StreamWriter(path))
            {
                foreach (var item in list)
                {
                    sr.WriteLine(item.FilePath);
                }
            }

            return path;
        }


        private void HideProgress()
        {
            GridProgressBar.Visibility = Visibility.Collapsed;
            sprocketControl2.IsIndeterminate = false;
            progressBarDrop.Value = 0;
            TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
            TaskbarManager.Instance.SetProgressValue(0, 0);
            TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);
        }

        private string OctetsToMo(long _tailleOctets)
        {
            StringBuilder StrSize = new StringBuilder(64);
            StrFormatByteSize64(_tailleOctets, StrSize, 64U);

            return StrSize.ToString();
        }

        private void SaveChanges(DbContext dbContext)
        {
            try //on essaie de sauvegarder les changements en cas de bug car ca casse les couilles sinon.
            {
                dbContext.SaveChanges();
            }
            catch (DbEntityValidationException dbEx) //attrape l'erreur
            {
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
            }
        }

        private void ShowAllEpisodes()
        {
            TextBlockSerieName.Text = seriesContext.Series.Count() + " Series - " + seriesContext.Episodes.Count() + " Episodes";
            TextBlockSerieName.Visibility = Visibility.Visible;
            TxtBckEpisodesNumber.Visibility = Visibility.Collapsed;

            ListBoxImage.Visibility = Visibility.Hidden; //listbox image caché
            DockPanelVueDetaillee.Visibility = Visibility.Visible; //dockpanel  vue detail visible
            ListBoxSaison.Visibility = Visibility.Visible;

            seriesContext.Episodes.Load();//charge l'entité episodes
            seriesContext.Series.Load(); //charge l'entité series

            //DataGridEpisodes.ItemsSource = seriesContext.Episodes.Local;
            DockPanelVueDetaillee.DataContext = seriesContext.Series.Local.OrderBy(s => s.Name); //defini le datacontext => Series ragné par nom
            if (ListBoxSaison.Items.Count != 0)
                ListBoxSaison.SelectedItem = ListBoxSaison.Items[0]; //pas d'item selectionné

            //definie la source du datagrid
            //DataGridEpisodes.ItemsSource = seriesContext.Episodes.Local.OrderBy(s => s.Saison.Serie.Name).ThenBy(s => s.Saison.Num).ThenBy(s => s.Num);
            DataGridEpisodes.ItemsSource = seriesContext.Episodes.Local.OrderByDescending(s => s.AddDate);
        }

        private void ShowFilteredEpisodes()
        {

            //TextBlockSerieName.Text = seriesContext.Series.Count() + " Series - " + seriesContext.Episodes.Count() + " Episodes";
            TxtBckEpisodesNumber.Visibility = Visibility.Visible;
            TextBlockSerieName.Visibility = Visibility.Collapsed;

            ListBoxSaison.Visibility = Visibility.Collapsed;
            ListBoxImage.Visibility = Visibility.Hidden; //listbox image caché
            DockPanelVueDetaillee.Visibility = Visibility.Visible; //dockpanel  vue detail visible

            seriesContext.Episodes.Load();//charge l'entité episodes
            seriesContext.Series.Load(); //charge l'entité series
        }

        private void ShowImageAndDetail(bool show)
        {
            if (show)//on affiche les detail
            {
                GridDetailSerie.Visibility = Visibility.Visible;
            }
            else //on masque
            {
                GridDetailSerie.Visibility = Visibility.Collapsed;
            }
        }

        private void ShowProgress(bool isInderterminate)
        {
            GridProgressBar.Visibility = Visibility.Visible;
            sprocketControl2.IsIndeterminate = true;

            if (isInderterminate)
            {
                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Indeterminate);
                progressBarDrop.IsIndeterminate = true;
            }
            else
            {
                progressBarDrop.IsIndeterminate = false;
                progressBarDrop.Value = 0;
                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
                TaskbarManager.Instance.SetProgressValue(0, 100);
            }
        }

        /// <summary>
        /// Afficher que les series avec les images
        /// </summary>
        private void ShowSeriesOnly()
        {
            ListBoxImage.Visibility = Visibility.Visible;
            DockPanelVueDetaillee.Visibility = Visibility.Hidden;

            if (seriesContext != null)
                TextBlockSerieName.Text = seriesContext.Series.Count() + " Series";

            toutBtn.IsChecked = false;
            seriesBtn.IsChecked = true;
            recentBtn.IsChecked = false;
            nonVueBtn.IsChecked = false;
        }

        private string UpdateSizeInStatutBar()
        {
            long sizeInOctets = 0;
            seriesContext.Episodes.Load();

            Parallel.For(0, seriesContext.Episodes.Count(), delegate(int i)
            {
                //if (seriesContext.Episodes.Local[i].Taille != null)
                long number;
                try
                {
                    if (seriesContext.Episodes.Local[i] != null)
                    {
                        bool result = long.TryParse(seriesContext.Episodes.Local[i].Taille.ToString(), out number);
                        if (result)
                        {
                            sizeInOctets += number;
                        }
                    }
                }
                catch (Exception)
                {
                }
            });

            return OctetsToMo(sizeInOctets);
        }

        //fin octet => Mo
        private void UpdateView()
        {
            seriesContext.SaveChanges();
            DataGridEpisodes.Items.Refresh();
        }
        private void WatchEpisode(Episodes episode)
        {
            if (episode != null && File.Exists(episode.FilePath))
            {
                try
                {
                    Process.Start(episode.FilePath);
                    episode.Saw = true;
                    TraitementText = ":) - Lecture en cours";
                    seriesContext.SaveChanges();
                    DataGridEpisodes.Items.Refresh();
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                    TraitementText = "! - Erreur";
                }
            }
            else
                TraitementText = "! - Fichier introuvable";
        }
        #endregion Méthode

        private void ListBoxImage_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //ListBoxImage.ItemTemplateSelector = new SeriesDataTemplateSelector();
        }

        private void LastEpisodes_Click_Handler(object sender, RoutedEventArgs e)
        {
            Series se = ListBoxImage.SelectedItem as Series;

            if (se != null)
            {
                Saisons s = se.Saisons.OrderBy(x => x.Num).Last();
                if (s.Episodes.Count > 0)
                {
                    Episodes ep = s.Episodes.OrderBy(x => x.Num).Last(x => x.FilePath != null);
                    try
                    {
                        if (String.IsNullOrWhiteSpace(ep.FilePath))
                            return;
                        else
                            Process.Start(ep.FilePath);
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }
            }
        }

        private void Menu_AddNewSerie_Click(object sender, RoutedEventArgs e)
        {
            Series newSerie = new Series();
            AddSerie window = new AddSerie(newSerie);
            window.ShowDialog();

            if (window.DialogResult.Value)
            { }
            else { }
        }

        private void Menu_Maiday_Click(object sender, RoutedEventArgs e)
        {
            //TODO
        }
    }

    #region Convertisseur
    #region datatemplateselector
    public class SeriesDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item != null && item is Series)
            {
                Series serie = item as Series;
                //if (serie == null)
                //    return null;
                //if (serie.Name == "Revolution")
                //    return null;
                Window window = System.Windows.Application.Current.MainWindow;
                ListBox list = window.FindName("ListBoxImage") as ListBox;

                Series selectedSerie = list.SelectedItem as Series;

                if (selectedSerie != null && selectedSerie.Name == serie.Name)
                {
                    return window.FindResource("detailedTemplate") as DataTemplate;
                }
                else
                {
                    return window.FindResource("basicTemplate") as DataTemplate;
                }
            }
            else
            { }

            return null;
        }
    }
    #endregion datatemplateselector

    /// <summary>
    /// bool to visible ou collapse
    /// </summary>
    public class BooleanToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value is Visibility && (Visibility)value == Visibility.Visible;
        }
    }

    public class GetLastEpisode : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Series se = value as Series;

            if (se.Name == "Revolution")
            { }
            if (se != null)
            {
                Episodes ep;
                Saisons s = se.Saisons.OrderBy(x => x.Num).Last();

                if (s.Episodes.Count > 0)
                    try
                    {
                        ep = s.Episodes.OrderBy(x => x.Num).Last(x => x.AirDate != null);
                    }
                    catch (Exception e)
                    {
                        return null;
                    }
                else
                    return null;
                try
                {
                    if (Int32.Parse(parameter.ToString()) == 1)
                    {
                        //if (ep.AirDate != null)
                        return ep.AirDate.Value.ToShortDateString();
                        //else return null;
                    }

                    else if (Int32.Parse(parameter.ToString()) == 2)
                    {
                        //if (ep.AirDate != null && ep.FilePath != null)
                        if (ep.FilePath != null && ep.AddDate != null)
                            return ep.AddDate.Value.ToShortDateString();
                        else return null;
                    }
                    else //if (Int32.Parse(parameter.ToString()) == 3)
                        return null;// non vue
                }
                catch (Exception e)
                {
                    return null;
                }

            }
            else
                return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }



    public class CollectionToWidth : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int l = (int)value;
            double total;
            if (l > 0)
                total = 175;

            else total = 0;
            return (total);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class DominantColorOfImage : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Color color;
            if (null == value)
            {
                color = new Color();
                color.A = 0;
                color.B = 0;
                color.G = 0;
                return color;
            }

            BitmapSource bts;

            if (Int32.Parse(parameter.ToString()) == 2)
            {
                ImageBrush img = value as ImageBrush;
                bts = img.ImageSource as BitmapSource;
            }
            else
            {
                bts = ((Image)value).Source as BitmapSource;

            }

            color = MainWindow.CalculateAverageColor(bts);

            return new SolidColorBrush(color);


            // You can support here more source types if you wish
            // For the example I throw an exception

            //Type type = value.GetType();
            //throw new InvalidOperationException("Unsupported type [" + type.Name + "]");
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    /// <summary>
    /// converteur pour la hauteur des images de la listboximage
    /// </summary>
    public class HeightImage : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // 680x1000 => 17/25

            double dd = ((double)value - 20) * 1.47;

            return dd;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    /// <summary>
    /// true to false et false to true
    /// </summary>
    [ValueConversion(typeof(bool), typeof(bool))]
    public class InvertBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool booleanValue = (bool)value;
            return !booleanValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool booleanValue = (bool)value;
            return !booleanValue;
        }
    }

    public class ItemIsSelected : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    /// <summary>
    /// converter pour afficher la taille en Mo
    /// </summary>
    public class TailleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //string sizeInMo = StrFormatByteSize64((long)value);
            //string chemin = Settings.Default.Serie + "\\" + nomSerie + "\\" + nomSerie + ".jpg";
            long v = 0;
            if (value != null)
                v = long.Parse(((double)value).ToString());
            return StrFormatByteSize64((long)v); ;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }

        [DllImport("shlwapi")]
        private static extern int StrFormatByteSize64(long qdw, StringBuilder pszBuf, uint cchBuf);

        private static string StrFormatByteSize64(long qdw)
        {
            StringBuilder StrSize = new StringBuilder(64);
            StrFormatByteSize64(qdw, StrSize, 64U);
            return StrSize.ToString();
        }
    }

    /// <summary>
    /// uri to image
    /// </summary>
    public class UriToBitmapConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.DecodePixelWidth = 150;
                bi.CacheOption = BitmapCacheOption.OnLoad;
                bi.UriSource = new Uri(value.ToString());
                bi.EndInit();
                return bi;
            }
            catch (Exception e)
            {
                e.ToString();
                return null;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }

    /// <summary>
    /// pour la derniere colonne du dg
    /// </summary>
    public class WidthConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            DataGrid l = value as DataGrid;
            double total = 0;
            for (int i = 0; i < l.Columns.Count - 1; i++) // Tout sauf la dernière colonne
            {
                total += i;
            }
            return (l.ActualWidth - total);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class WidthDivise : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double width = (double)value;
            double div = Double.Parse((string)parameter, CultureInfo.InvariantCulture);
            double widthFinal = width / div;
            return widthFinal;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    /// <summary>
    /// converter pour la largeur des images de la listboximage
    /// </summary>
    public class WidthImage : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // 680x1000 => 17/25

            double dd = ((double)value - 20);

            return dd;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    /// <summary>
    /// value du zoom - 50
    /// </summary>
    public class WidthZoom : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double width = (double)value;
            double widthFinal = width - 50;
            return widthFinal;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }
    }
    #endregion Convertisseur

    #region CustomSort

    internal class CustomSortAsc : IComparer
    {
        public int Compare(object _x, object _y)
        {
            Episodes x = _x as Episodes;
            Episodes y = _y as Episodes;
            if (x == null || y == null)
                return 0;

            int stringCompare = (int)(x.Saisons.Series.IdTvdb).Value.CompareTo(y.Saisons.Series.IdTvdb);
            int intCompare = x.Saisons.Num.CompareTo(y.Saisons.Num);

            if (stringCompare == 0)
            {
                if (intCompare == 0)
                {
                    if (x.Num < y.Num)
                        return -1;
                    else
                        return 1;
                }
                else
                    return intCompare;
            }
            else
                return stringCompare;
        }
    }

    #endregion CustomSort

    public partial class bddEntities : DbContext
    {
        //public SeriesEntities(string fileWithPath)
        //{
        //    this.Database.Connection.ConnectionString = fileWithPath;
        //}

        //public SeriesEntities()
        //    : base("name=SeriesEntities")
        //{

        //}

        public bddEntities(string connectionString)
            : base(connectionString)
        {

        }
    }
}
